﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using VIP.Infrastructure;
using VIP.Infrastructure.Exceptions;

namespace WebApplication.Filters
{
    public class GlobalExceptionFilterAsync : IAsyncExceptionFilter
    {
        private readonly Microsoft.Extensions.Logging.ILogger _loger;// NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();

        //private readonly IHttpContextAccessor _httpContextAccessor;
        public GlobalExceptionFilterAsync(ILoggerFactory logger)
        {
            _loger = logger.CreateLogger("GlobalExceptionFilterAsync");
            //_loger = logger;
            //_httpContextAccessor = httpContextAccessor;
        }
        public Task OnExceptionAsync(ExceptionContext context)
        {
            if (context.ExceptionHandled == true)
            {
                return Task.CompletedTask;
            }
            //业务错误
            if (context.Exception is VIPBusinessException)
            {
                var e = context.Exception as VIPBusinessException;
                context.Result = new JsonResult(new ApiResponse<dynamic>()
                {
                    Code = -1,
                    Data = null,
                    Message = e.ErrorMessage
                });
                logBusinessException(e, context.HttpContext);
            }
            //非业务错误-写错误日志
            logException(context.Exception);
            context.Result = new JsonResult(new ApiResponse<dynamic>()
            {
                Code = -1,
                Data = null,
                Message = context.Exception.Message
            });
            context.ExceptionHandled = true;
            return Task.CompletedTask;
        }
        /// <summary>
        /// 异常写日志文件
        /// </summary>
        /// <param name="e"></param>
        private void logException(Exception e)
        {
            StringBuilder sbExpMsg = new StringBuilder();
            //sbExpMsg.Append($"IP:{_httpContextAccessor.HttpContext.Request.Host}\r\n");

            if (e.InnerException != null)
            {
                sbExpMsg.Append($"LogInfo:{e.InnerException}\r\n");
            }
            else
            {
                sbExpMsg.Append($"LogInfo:{e.Message}\r\n");
            }
            sbExpMsg.Append($"StackTrace:{e.StackTrace}\r\n");
            sbExpMsg.Append($"DateTime:{DateTime.Now}\r\n");
            sbExpMsg.Append("---------------------------------------------------\r\n");
            _loger.LogError(sbExpMsg.ToString());
        }

        /// <summary>
        /// 业务异常写日志文件
        /// </summary>
        /// <param name="e"></param>
        /// <param name="context"></param>
        private void logBusinessException(VIPBusinessException e, HttpContext context)
        {
            StringBuilder sbExpMsg = new StringBuilder();
            sbExpMsg.Append($"----------------------------BusinessException------------------------\r\n");
            sbExpMsg.Append($"Path:{context.Request.Path}\r\n");
            sbExpMsg.Append($"ErrorMessage:{e.ErrorMessage}\r\n");
            string content = string.Empty;
            try
            {
                StreamReader streamReader = new StreamReader(context.Request.Body);
                content = streamReader.ReadToEnd();
            }
            catch
            {
                content = "读取content出错";
            }


            sbExpMsg.Append($"Content:{content}\r\n");
            sbExpMsg.Append($"QueryString:{context.Request.QueryString}\r\n");
            sbExpMsg.Append($"DateTime:{DateTime.Now}\r\n");
            _loger.LogError(sbExpMsg.ToString());
        }


    }
}
